@page "/JSInterop"
@using BlazorSample.JsInteropClasses
@inject IJSRuntime JSRuntime

<h1>JavaScript Interop</h1>

<h2>Invoke JavaScript functions from .NET methods</h2>

<button type="button" class="btn btn-primary" @onclick="TriggerJsPrompt">
    Trigger JavaScript Prompt
</button>

<h3 id="welcome" style="color:green;font-style:italic"></h3>

@code {
    public async Task TriggerJsPrompt()
    {
        // showPrompt is implemented in wwwroot/exampleJsInterop.js
        var name = await JSRuntime.InvokeAsync<string>(
                "exampleJsFunctions.showPrompt",
                "What's your name?");
        // displayWelcome is implemented in wwwroot/exampleJsInterop.js
        await JSRuntime.InvokeVoidAsync(
                "exampleJsFunctions.displayWelcome",
                $"Hello {name}! Welcome to Blazor!");
    }
}

<p>
    When <code>TriggerJsPrompt</code> is executed by selecting the component's <b>Trigger JavaScript Prompt</b> button, the JavaScript <code>showPrompt</code> function provided in the <em>wwwroot/exampleJsInterop.js</em> file is executed.
</p>
<p>
    The <code>showPrompt</code> function accepts user input (the user's name), which is HTML-encoded and returned to the <code>Prompt</code> method and ultimately back to the component. The component stores the user's name in a local variable, <code>name</code>.
</p>
<p>
    The string stored in <code>name</code> is incorporated into a welcome message, which is passed to a JavaScript function, <code>displayWelcome</code>, which renders the welcome message into a heading tag.
</p>

<h2>Invoke .NET methods from JavaScript functions</h2>

<p>Examine the console output in your broswer's developer tools when selecting the following buttons to trigger .NET static and instance methods.</p>

<p>When the button to call the C# static method is selected, the JavaScript <code>returnArrayAsyncJs</code> function in <em>wwwroot/exampleJsInterop.js</em> is executed. The function uses <code>DotNet.invokeMethodAsync</code> to call the C# static method <code>ReturnArrayAsync</code>. The C# method returns an integer array to the JavaScript function, which writes the array to the console.</p>

<p>When the button to call the C# instance method is selected, <code>ExampleJsInterop.CallHelloHelperSayHello</code> is called and passes a name to the method. <code>ExampleJsInterop.CallHelloHelperSayHello</code> invokes the JavaScript function <code>sayHello</code> with a new instance of <code>HelloHelper</code>. The name is passed to <code>HelloHelper</code>'s constructor, which sets the <code>HelloHelper.Name</code> property. When the JavaScript function <code>sayHello</code> is executed, <code>HelloHelper.SayHello</code> returns the <code>Hello, {Name}!</code> message, which is written to the console.</p>

<button type="button" class="btn btn-primary"
        onclick="exampleJsFunctions.returnArrayAsyncJs()">
    Trigger .NET static method ReturnArrayAsync
</button>

@code {
    [JSInvokable]
    public static Task<int[]> ReturnArrayAsync()
    {
        return Task.FromResult(new int[] { 1, 2, 3 });
    }
}

<button type="button" class="btn btn-primary" @onclick="TriggerNetInstanceMethod">
    Trigger .NET instance method HelloHelper.SayHello
</button>

@code {
    public async Task TriggerNetInstanceMethod()
    {
        var exampleJsInterop = new ExampleJsInterop(JSRuntime);
        await exampleJsInterop.CallHelloHelperSayHello("Blazor");
    }
}
